#include "include.h"

void bt_noaec_process(u8 *ptr, u32 samples, int ch_mode);
void bt_aec_process(u8 *ptr, u32 samples, int ch_mode);
void bt_sco_tx_process(u8 *ptr, u32 samples, int ch_mode);
void bt_alc_process(u8 *ptr, u32 samples, int ch_mode);
void aux_sdadc_process(u8 *ptr, u32 samples, int ch_mode);
void speaker_sdadc_process(u8 *ptr, u32 samples, int ch_mode);
void usbmic_sdadc_process(u8 *ptr, u32 samples, int ch_mode);
void karaok_sdadc_process(u8 *ptr, u32 samples, int ch_mode);
void opus_sdadc_process(u8 *ptr, u32 samples, int ch_mode);
void voice_assistant_sdadc_process(u8 *ptr,u32 samples,int ch_mode);
void ttp_sdadc_process(u8 *ptr, u32 samples, int ch_mode);
void bt_iodm_sdadc_process(u8 *ptr, u32 samples, int ch_mode);


#if UDE_MIC_EN
    #define usbmic_sdadc_callback   usbmic_sdadc_process
#else
    #define usbmic_sdadc_callback   sdadc_dummy
#endif // UDE_MIC_EN

#if BT_AEC_EN || BT_NLMS_AEC_EN
    #define bt_sdadc_callback    bt_aec_process
#elif BT_ALC_EN
    #define bt_sdadc_callback    bt_alc_process
#elif BT_SNDP_EN || BT_SNDP_DMIC_EN || BT_SCO_AINS2_EN || BT_SCO_DMNS_EN || BT_SCO_DNN_EN || BT_SCO_DMDNN_EN || BT_SNDP_DMIC_DNN_EN
	#define bt_sdadc_callback    bt_noaec_process
#else
    #define bt_sdadc_callback    bt_sco_tx_process
#endif //BT_AEC_EN

#if DUEROS_SUPPORT_EN
    #define opus_sdadc_callback   opus_sdadc_process
#else
    #define opus_sdadc_callback   sdadc_dummy
#endif


#if IODM_TEST_MODE
    #define bt_iodm_sdadc_callback  bt_iodm_sdadc_process
#else
    #define bt_iodm_sdadc_callback  sdadc_dummy
#endif // IODM_TEST_MODE

static u8 bt_mic_dig_gain;
static u8 bt_mic_anl_gain;
static u8 bt_mic_pin;

//AUX analog gain -42DB~+3DB
//MIC analog gain: 0~13(共14级), step 3DB (3db ~ +42db)
//adadc digital gain: 0~63, step 0.5 DB, 保存在gain的低6bit
const sdadc_cfg_t rec_cfg_tbl[] = {
/*   通道,             增益,        采样率,      通路控制,    样点数,   回调函数*/
//    {AUX_CHANNEL_CFG,  (2 << 6),    SPR_44100,   ADC2DAC_EN,    256,    aux_sdadc_callback},            /* AUX     */
//    {MIC_CHANNEL_CFG,  (8 << 6),    SPR_44100,   ADC2DAC_EN,    256,    speaker_sdadc_callback},        /* SPEAKER */
//    {MIC_CHANNEL_CFG,  (12 << 6),   SPR_8000,    ADC2DAC_EN,    128,    bt_sdadc_callback},             /* BTMIC   */
//    {MIC_CHANNEL_CFG,  (12 << 6),   SPR_48000,   ADC2DAC_EN,    128,    usbmic_sdadc_callback},         /* USBMIC  */
//    {MIC_CHANNEL_CFG,  (12 << 6),   SPR_44100,   ADC2SRC_EN,    256,    karaok_sdadc_callback},         /* KARAOK  */
//    {MIC_CHANNEL_CFG,  (12 << 6),   SPR_16000,   ADC2DAC_EN,    256,    opus_sdadc_callback},           /* opus  */
//    {MIC_CHANNEL_CFG,  (6 << 6),    SPR_44100,   ADC2SRC_EN,    256,    ttp_sdadc_callback},            /* TRANSPARENCY  */
//    {MIC_CHANNEL_CFG,  (6 << 6),    SPR_8000,    ADC2DAC_EN,    256,    sdadc_dummy},                   /* BTVOICE  */
//    {MIC_CHANNEL_CFG,  (6 << 6),    SPR_8000,    ADC2DAC_EN,    256,    bt_iodm_sdadc_callback},        /* IODM_MIC_TEST*/
};

AT(.com_rodata.mic.table)
const u16 mic_ch_tbl[] = {CH_MICL0, CH_MICL0, CH_VUSBL, 0, CH_MICR0, CH_MICR0, CH_VUSBR, 0};


AT(.com_text.mictrim)
u32 mic_channel_get_pin(void)
{
    return bt_mic_pin;
}

void mic_channel_init(void)
{
    if (xcfg_cb.micl_en) {
        bt_mic_dig_gain = 0; //xcfg_cb.bt_dig_gain
        bt_mic_anl_gain = xcfg_cb.micl_anl_gain;
        bt_mic_pin = xcfg_cb.micl_sel;
    } else if (xcfg_cb.micr_en) {
        bt_mic_dig_gain = 0; //xcfg_cb.bt_dig_gain
        bt_mic_anl_gain = xcfg_cb.micr_anl_gain;
        bt_mic_pin = xcfg_cb.micr_sel;
    } else {
        bt_mic_dig_gain = 0; //xcfg_cb.bt_dig_gain
        bt_mic_anl_gain = 0;
        bt_mic_pin = 0;
    }
}

void mic_channel_get_param(u16 *channel, u16 *gain)
{
    if(channel != NULL) {
        *channel  = mic_ch_tbl[bt_mic_pin];
    }

    if(gain != NULL) {
        *gain = ((u16)bt_mic_anl_gain << 6) | bt_mic_dig_gain;
    }
}

AT(.com_rodata.aux.table)
const u16 aux_ch_tbl[] = {
    (CH_AUXL_PB1 | CH_AUXR_PB2),
    (CH_AUXL_PA6 | CH_AUXR_PA7),
    (CH_AUXL_PE6 | CH_AUXR_PE7),
    (CH_AUXL_PF4 | CH_AUXR_PF5),
};

void aux_channel_get_param(u16 *channel, u16 *gain)
{
    if(channel != NULL) {
        *channel  = aux_ch_tbl[1];
    }

    if(gain != NULL) {
        *gain = ((u16)2 << 6) | 0;
    }
}

void audio_path_init(u8 path_idx)
{
    sdadc_cfg_t cfg;
    memcpy(&cfg, &rec_cfg_tbl[path_idx], sizeof(sdadc_cfg_t));

    if (path_idx == AUDIO_PATH_BTMIC || path_idx == AUDIO_PATH_KARAOK || path_idx == AUDIO_PATH_BTVOICE || path_idx == AUDIO_PATH_OPUS || path_idx == AUDIO_PATH_TTP) {
        if (path_idx == AUDIO_PATH_BTMIC) {
            if (sys_cb.hfp_karaok_en) {
                memcpy(&cfg, &rec_cfg_tbl[AUDIO_PATH_KARAOK], sizeof(sdadc_cfg_t));
                cfg.sample_rate = SPR_48000;
            } else {
        #if BT_AEC_EN || BT_ALC_EN || BT_NLMS_AEC_EN
                if (xcfg_cb.bt_aec_en) {
                    cfg.callback = bt_aec_process;
                } else if (xcfg_cb.bt_alc_en) {
                    cfg.callback = bt_alc_process;
                } else {
                    cfg.callback = bt_sco_tx_process;
                }
        #endif
            }
        }

        mic_channel_get_param(&cfg.channel, &cfg.gain);
    }
#if IODM_TEST_MODE
    else if (path_idx == AUDIO_PATH_IODM_MIC_TEST) {
        iodm_test_set_mic_param(&cfg.channel,&cfg.gain);
    }
#endif


    sdadc_init(&cfg);
}

void audio_path_start(u8 path_idx)
{
    sdadc_cfg_t cfg;
    memcpy(&cfg, &rec_cfg_tbl[path_idx], sizeof(sdadc_cfg_t));

    if (path_idx == AUDIO_PATH_BTMIC || path_idx == AUDIO_PATH_KARAOK || path_idx == AUDIO_PATH_BTVOICE || path_idx == AUDIO_PATH_OPUS || path_idx == AUDIO_PATH_TTP) {
        mic_channel_get_param(&cfg.channel, NULL);
    }
#if IODM_TEST_MODE
    else if (path_idx == AUDIO_PATH_IODM_MIC_TEST){
        iodm_test_set_mic_param(&cfg.channel, &cfg.gain);
    }
#endif

    sdadc_start(cfg.channel);
}

void audio_path_exit(u8 path_idx)
{
    sdadc_cfg_t cfg;
    memcpy(&cfg, &rec_cfg_tbl[path_idx], sizeof(sdadc_cfg_t));

    if (path_idx == AUDIO_PATH_BTMIC || path_idx == AUDIO_PATH_KARAOK || path_idx == AUDIO_PATH_BTVOICE || path_idx == AUDIO_PATH_OPUS || path_idx == AUDIO_PATH_TTP) {
        mic_channel_get_param(&cfg.channel, NULL);
    }
#if IODM_TEST_MODE
    else if (path_idx == AUDIO_PATH_IODM_MIC_TEST){
        iodm_test_set_mic_param(&cfg.channel, &cfg.gain);
    }
#endif

    sdadc_exit(cfg.channel);

    adpll_spr_set(DAC_OUT_SPR);
}



